home *** CD-ROM | disk | FTP | other *** search
/ Pocket PC Game Programming / Pocket PC Game Programming.iso / source.exe / CH15 / GameLibrary / GameLibrary.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-28  |  15.9 KB  |  609 lines

  1. //////////////////////////////////////////////////////////////////////
  2. // Pocket PC Game Programming
  3. //
  4. // CGameLibrary Source File
  5. //
  6. // This file includes the CGameLibrary class implementation.
  7. //
  8. //////////////////////////////////////////////////////////////////////
  9.  
  10. #include "stdafx.h"
  11. #include "GameLibrary.h"
  12.  
  13. CGameLibrary *CGameLibrary::pGameLib = NULL;
  14.  
  15. //////////////////////////////////////////////////////////////////////
  16. // CGameLibrary::CGameLibrary constructor
  17. //
  18. //////////////////////////////////////////////////////////////////////
  19. CGameLibrary::CGameLibrary(HINSTANCE hInst, LPTSTR szNewWindowClass)
  20. {
  21.     pGameLib = this;
  22.     bHibernate = TRUE;
  23.     bFullscreen = FALSE;
  24.     hInstance = hInst;
  25.     hWindow = NULL;
  26.     iFrameRate = 60;
  27.     bGAPIDisplay = FALSE;
  28.  
  29.     if (wcslen(szNewWindowClass) > 0)
  30.         wcscpy(szWindowClass, szNewWindowClass);
  31.     else
  32.         wcscpy(szWindowClass, _T("<Unnamed Window Class>"));
  33.     
  34.     if (wcslen(szTitle) == 0)
  35.         wcscpy(szTitle, _T("<Unnamed Title>"));
  36.  
  37. }
  38.  
  39. //////////////////////////////////////////////////////////////////////
  40. // CGameLibrary::~CGameLibrary destructor
  41. //
  42. //////////////////////////////////////////////////////////////////////
  43. CGameLibrary::~CGameLibrary()
  44. {
  45. }
  46.  
  47. //////////////////////////////////////////////////////////////////////
  48. // CGameLibrary::Initialize
  49. // Performs both InitInstance and MyRegisterClass processes
  50. //////////////////////////////////////////////////////////////////////
  51. BOOL CGameLibrary::Initialize(int nCmdShow)
  52. {
  53.     WNDCLASS wc;
  54.     RECT rect;
  55.  
  56.     //If it is already running, then focus on the window
  57.     hWindow = FindWindow(szWindowClass, szTitle);    
  58.     if (hWindow) 
  59.     {
  60.         SetForegroundWindow ((HWND) (((DWORD)hWindow) | 0x01));
  61.         return 0;
  62.     } 
  63.  
  64.     //Register the window class
  65.     wc.style            = CS_HREDRAW | CS_VREDRAW;
  66.     wc.lpfnWndProc        = (WNDPROC) WndProc;
  67.     wc.cbClsExtra        = 0;
  68.     wc.cbWndExtra        = 0;
  69.     wc.hInstance        = GetInstance();
  70.     wc.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(GetIcon()));
  71.     wc.hCursor            = 0;
  72.     wc.hbrBackground    = (HBRUSH) GetStockObject(WHITE_BRUSH);
  73.     wc.lpszMenuName        = 0;
  74.     wc.lpszClassName    = szWindowClass;
  75.     
  76.     if (!RegisterClass(&wc))
  77.     {
  78.         Error(_T("Could not register window class!"));
  79.     }
  80.     
  81.     GetClientRect(hWindow, &rect);
  82.  
  83.     if (GetFullscreen() || G_Enabled())
  84.     {
  85.         hWindow = CreateWindow(szWindowClass, szTitle, 
  86.             WS_VISIBLE, 0, 0, 
  87.             GetSystemMetrics(SM_CXSCREEN), 
  88.             GetSystemMetrics(SM_CYSCREEN), 
  89.             NULL, NULL, hInstance, NULL);
  90.     } else {
  91.         hWindow = CreateWindow(szWindowClass, szTitle, 
  92.             WS_VISIBLE,    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  93.             CW_USEDEFAULT, NULL, NULL, hInstance, NULL );
  94.     }
  95.     if (!hWindow)
  96.     {    
  97.         Error(_T("Could not create the game window!"));
  98.         return FALSE;
  99.     }
  100.  
  101.     ShowWindow(hWindow, nCmdShow);
  102.     UpdateWindow(hWindow);
  103.  
  104.     if (G_Enabled())
  105.     {
  106.         //initialize the GAPI display for fullscreen
  107.         if (GXOpenDisplay(GetWindow(), GX_FULLSCREEN) == 0) {
  108.             return FALSE;
  109.         }
  110.  
  111.         //retrieve display properties
  112.         gxDisplay = GXGetDisplayProperties();
  113.  
  114.         //make sure 16-bit color is available
  115.         if ((GetBitsPerPixel() != 16) || (!IsScreenFormat565()))
  116.         {
  117.             Error(_T("Full 16-bit color display is required!"));
  118.             GXCloseDisplay();
  119.             return FALSE;
  120.         }
  121.     }
  122.  
  123.     //*** New code for Chapter 11 ********************************
  124.     
  125.     //set up buttons for exclusive control
  126.     GXOpenInput();
  127.     gxKeys = GXGetDefaultKeys(GX_NORMALKEYS);
  128.  
  129.     //************************************************************
  130.  
  131.     return TRUE;
  132. }
  133.  
  134. //////////////////////////////////////////////////////////////////////
  135. // CGameLibrary::EventHandler
  136. // Handles events passed from WndProc
  137. //////////////////////////////////////////////////////////////////////
  138. LRESULT CGameLibrary::EventHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  139. {
  140.  
  141.     //*** 02/11 for chapter 11 ***************************************************
  142.     short vkKey;
  143.     POINT pt;
  144.     BOOL bButton;
  145.  
  146.     switch (message) 
  147.     {
  148.         case WM_CREATE:
  149.             SetWindow(hWnd);
  150.             SetForegroundWindow(GetWindow());
  151.             GameStart(hWnd);
  152.             break;
  153.  
  154.         case WM_HIBERNATE:
  155.             SetHibernate(TRUE);
  156.             SHFullScreen(GetWindow(), SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON);
  157.             break;
  158.  
  159.         case WM_KILLFOCUS:
  160.             SetHibernate(TRUE);
  161.             if (G_Enabled())
  162.                 GXSuspend();
  163.             break;
  164.  
  165.         case WM_ACTIVATE:
  166.             GameActivate(hWnd);
  167.             if (GetHibernate())
  168.             {
  169.                 SetHibernate(FALSE);
  170.             }
  171.             if (G_Enabled())
  172.                 GXResume();
  173.             else
  174.                 if (GetFullscreen())
  175.                 {
  176.                     if( wParam == WA_INACTIVE )
  177.                         SHFullScreen(hWnd, SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON);
  178.                     else
  179.                         SHFullScreen(hWnd, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON);
  180.                 }
  181.  
  182.             break;
  183.  
  184.         case WM_PAINT:
  185.             GamePaint(hWnd);
  186.              break;
  187.  
  188.         case WM_LBUTTONDOWN:
  189.             StylusDown(LOWORD(lParam), HIWORD(lParam));
  190.             break;
  191.  
  192.         case WM_MOUSEMOVE:
  193.             StylusMove(LOWORD(lParam), HIWORD(lParam));
  194.             break;
  195.  
  196.         case WM_LBUTTONUP:
  197.             StylusUp(LOWORD(lParam), HIWORD(lParam));
  198.             break;
  199.  
  200. //*** 02/11 for chapter 11 *******************************************************
  201.         case WM_KEYDOWN:
  202.             vkKey = (short)wParam;
  203.             bButton = TRUE;
  204.  
  205.             if (vkKey == gxKeys.vkUp)
  206.             {
  207.                 pt = gxKeys.ptUp;
  208.                 vkKey = 0;
  209.             }
  210.  
  211.             else if (vkKey == gxKeys.vkDown)
  212.             {
  213.                 pt = gxKeys.ptDown;
  214.                 vkKey = 1;
  215.             }
  216.  
  217.             else if (vkKey == gxKeys.vkLeft)
  218.             {
  219.                 pt = gxKeys.ptLeft;
  220.                 vkKey = 2;
  221.             }
  222.  
  223.             else if (vkKey == gxKeys.vkRight)
  224.             {
  225.                 pt = gxKeys.ptRight;
  226.                 vkKey = 3;
  227.             }
  228.  
  229.             else if (vkKey == gxKeys.vkA)
  230.             {
  231.                 pt = gxKeys.ptA;
  232.                 vkKey = 4;
  233.             }
  234.  
  235.             else if (vkKey == gxKeys.vkB)
  236.             {
  237.                 pt = gxKeys.ptB;
  238.                 vkKey = 5;
  239.             }
  240.             
  241.             else if (vkKey == gxKeys.vkC)
  242.             {
  243.                 pt = gxKeys.ptC;
  244.                 vkKey = 6;
  245.             }
  246.  
  247.             else if (vkKey == gxKeys.vkStart)
  248.             {
  249.                 pt = gxKeys.ptStart;
  250.                 vkKey = 7;
  251.             }
  252.  
  253.             else if (vkKey == 192)
  254.             {
  255.                 pt = gxKeys.ptStart;
  256.                 vkKey = 8;
  257.             }
  258.  
  259.             else if (vkKey == 193)
  260.             {
  261.                 pt = gxKeys.ptStart;
  262.                 vkKey = 9;
  263.             }
  264.  
  265.             else
  266.                 bButton = FALSE;
  267.  
  268.             if (bButton)
  269.                 ButtonPress(vkKey, pt);
  270.  
  271.             break;
  272.  
  273. //*** 02/11 for chapter 11 *******************************************************
  274.         case WM_KEYUP:
  275.             vkKey = (short)wParam;
  276.             bButton = TRUE;
  277.  
  278.             if (vkKey == gxKeys.vkUp)
  279.             {
  280.                 pt = gxKeys.ptUp;
  281.                 vkKey = 0;
  282.             }
  283.  
  284.             else if (vkKey == gxKeys.vkDown)
  285.             {
  286.                 pt = gxKeys.ptDown;
  287.                 vkKey = 1;
  288.             }
  289.  
  290.             else if (vkKey == gxKeys.vkLeft)
  291.             {
  292.                 pt = gxKeys.ptLeft;
  293.                 vkKey = 2;
  294.             }
  295.  
  296.             else if (vkKey == gxKeys.vkRight)
  297.             {
  298.                 pt = gxKeys.ptRight;
  299.                 vkKey = 3;
  300.             }
  301.  
  302.             else if (vkKey == gxKeys.vkA)
  303.             {
  304.                 pt = gxKeys.ptA;
  305.                 vkKey = 4;
  306.             }
  307.  
  308.             else if (vkKey == gxKeys.vkB)
  309.             {
  310.                 pt = gxKeys.ptB;
  311.                 vkKey = 5;
  312.             }
  313.             
  314.             else if (vkKey == gxKeys.vkC)
  315.             {
  316.                 pt = gxKeys.ptC;
  317.                 vkKey = 6;
  318.             }
  319.  
  320.             else if (vkKey == gxKeys.vkStart)
  321.             {
  322.                 pt = gxKeys.ptStart;
  323.                 vkKey = 7;
  324.             }
  325.  
  326.             else if (vkKey == 192)
  327.             {
  328.                 pt = gxKeys.ptStart;
  329.                 vkKey = 8;
  330.             }
  331.  
  332.             else if (vkKey == 193)
  333.             {
  334.                 pt = gxKeys.ptStart;
  335.                 vkKey = 9;
  336.             }
  337.  
  338.             else
  339.                 bButton = FALSE;
  340.  
  341.             if (bButton)
  342.                 ButtonRelease(vkKey, pt);
  343.  
  344.             break;
  345.  
  346.         case WM_DESTROY:
  347.             GameEnd();
  348.             if (G_Enabled())
  349.                 GXCloseDisplay();
  350.             
  351. //*** 02/11 for chapter 11 *******************************************************
  352.             GXCloseInput();
  353.             
  354.             PostQuitMessage(0);
  355.             break;
  356.  
  357.         default:
  358.             return DefWindowProc(hWnd, message, wParam, lParam);
  359.  
  360.     }
  361.     return 0;
  362. }
  363.  
  364. //////////////////////////////////////////////////////////////////////
  365. // CGameLibrary::Error
  366. // Handles error messages for the library
  367. //////////////////////////////////////////////////////////////////////
  368. void CGameLibrary::Error(LPTSTR szError)
  369. {
  370.     TCHAR szMsg[100];
  371.  
  372.     wsprintf(szMsg, _T("%s:\n%s\n%s, %i"), szMsg, __FILE__, __LINE__);
  373.     MsgBox(szMsg);
  374. }
  375.  
  376.  
  377. //////////////////////////////////////////////////////////////////////
  378. // CGameLibrary::Shutdown
  379. // Sends the close window message to end the program
  380. //////////////////////////////////////////////////////////////////////
  381. void CGameLibrary::Shutdown() 
  382. {
  383.     PostMessage(hWindow, WM_CLOSE, 0, 0);
  384. }
  385.  
  386. //////////////////////////////////////////////////////////////////////
  387. // CGameLibrary::G_BeginDraw
  388. // Sets up the GAPI for drawing to video memory.
  389. //////////////////////////////////////////////////////////////////////
  390. void CGameLibrary::G_BeginDraw()
  391. {
  392.     if (G_Enabled())
  393.         GAPIVidMem = (unsigned char *)GXBeginDraw();
  394. }
  395.  
  396. //////////////////////////////////////////////////////////////////////
  397. // CGameLibrary::G_EndDraw
  398. // End the draw session and kill the video memory pointer.
  399. //////////////////////////////////////////////////////////////////////
  400. void CGameLibrary::G_EndDraw()
  401. {
  402.     if (G_Enabled())
  403.         GXEndDraw();
  404. }
  405.  
  406. ////////////////////////////////////////////////////////////
  407. //  FUNCTION: G_ClearScreen
  408. //
  409. //  PURPOSE:  Clears the GAPI screen using specified color
  410. //
  411. BOOL CGameLibrary::G_ClearScreen(COLOR color)
  412. {
  413.     G_BeginDraw();
  414.     for (int y = 0; y < ScreenHeight(); y++) {
  415.         for (int x = 0; x < ScreenWidth(); x++) {
  416.             G_DrawPixel16(G_GetVidMem(), x, y, color);
  417.         }
  418.     }
  419.     G_EndDraw();
  420.     return TRUE;
  421. }
  422.  
  423. ////////////////////////////////////////////////////////////
  424. //  FUNCTION: G_DrawPixel16
  425. //
  426. //  PURPOSE:  Draw pixel on a 16-bit display.
  427. //
  428. int CGameLibrary::G_DrawPixel16(unsigned char *VidMem, int X, int Y, COLOR color)
  429. {
  430.     unsigned short usColor;
  431.     int address;
  432.     
  433.     //find pixel location in video memory
  434.     address = (X * GetXPitch()) + (Y * GetYPitch());
  435.     
  436.     //set color bits for 565 packed format
  437.     usColor = (unsigned short) 
  438.               (((color.Red   & 0xf8) << 8) |
  439.                ((color.Green & 0xfc) << 3) | 
  440.                ((color.Blue  & 0xf8) >> 3) );
  441.  
  442.     //display pixel
  443.     *(unsigned short *)(VidMem + address) = usColor;
  444.  
  445.     return 0;
  446. }
  447.  
  448. ////////////////////////////////////////////////////////////
  449. //  FUNCTION: G_DrawSolidRect
  450. //
  451. //  PURPOSE:  Draws a solid rectangle using GAPI video memory.
  452. //
  453. void CGameLibrary::G_DrawSolidRect(unsigned char *VidMem, int iLeft, int iTop, int iRight, int iBottom, COLOR color)
  454. {
  455.     int x, y;
  456.  
  457.     for (y = iTop; y<=iBottom; y++)
  458.     {
  459.         for (x = iLeft; x<=iRight; x++)
  460.         {
  461.             G_DrawPixel16(VidMem, x, y, color);
  462.         }
  463.     }
  464. }
  465.  
  466. //////////////////////////////////////////////////////////////////////
  467. // FatalError
  468. // Displays error message and then ends program.
  469. //////////////////////////////////////////////////////////////////////
  470. void CGameLibrary::FatalError(LPTSTR lpStr)
  471. {
  472.     MessageBox(GetWindow(), lpStr, _T("Fatal Error"), MB_OK | MB_ICONERROR);
  473.     Shutdown();
  474. }
  475.  
  476.  
  477. //////////////////////////////////////////////////////////////////////
  478. // PrintText
  479. // Prints a Unicode string to the screen coordinates x,y
  480. //////////////////////////////////////////////////////////////////////
  481. void CGameLibrary::PrintText(HDC hdc, LPCTSTR strText, int x, int y, COLORREF color, int iBkMode)
  482. {
  483.     static TEXTMETRIC tm;
  484.     static int cxChar, cyChar, cxCaps;
  485.     static BOOL bFirst = TRUE;
  486.  
  487.     if (bFirst)
  488.     {
  489.         GetTextMetrics(hdc, &tm);
  490.         cxChar = tm.tmAveCharWidth;
  491.         cyChar = tm.tmHeight + tm.tmExternalLeading;
  492.         cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
  493.         bFirst = FALSE;
  494.     }
  495.  
  496.     SetTextColor(hdc, color);
  497.     SetBkMode(hdc, iBkMode);
  498.     ExtTextOut(hdc, x + cxChar, cyChar * y, 0, NULL, strText, wcslen(strText), NULL);
  499. }
  500.  
  501. //////////////////////////////////////////////////////////////////////
  502. // GetPath
  503. // Returns full pathname of a file in the current directory.
  504. //////////////////////////////////////////////////////////////////////
  505. LPWSTR CGameLibrary::GetPath(TCHAR *filename)
  506. {
  507.     TCHAR *lpFilename;
  508.     TCHAR *pDest;
  509.     int nStrLen;
  510.     int result;
  511.     int ch = '\\';
  512.  
  513.     lpFilename = new TCHAR[255];
  514.     nStrLen = GetModuleFileName(NULL, lpFilename, 255);
  515.     
  516.     pDest = wcsrchr(lpFilename, ch);
  517.     if (pDest != NULL)
  518.     {
  519.         result = pDest - lpFilename + 1;
  520.         lpFilename[result] = '\0';
  521.  
  522.         if (filename != NULL)
  523.             wcscat(lpFilename, filename);
  524.  
  525.         return lpFilename;
  526.     }
  527.     else
  528.         return NULL;
  529. }
  530.  
  531. //////////////////////////////////////////////////////////////////////
  532. // WndProc
  533. // Primary window callback function
  534. //////////////////////////////////////////////////////////////////////
  535. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  536. {
  537.     return GameLib()->EventHandler(hWnd, message, wParam, lParam);
  538. }
  539.  
  540. //////////////////////////////////////////////////////////////////////
  541. // WinMain
  542. // Main entry point of program (library)
  543. //////////////////////////////////////////////////////////////////////
  544. int WINAPI WinMain(    HINSTANCE hInstance,
  545.                     HINSTANCE hPrevInstance,
  546.                     LPTSTR    lpCmdLine,
  547.                     int       nCmdShow )
  548. {
  549.     MSG msg;
  550.     static iNewTime = 0;
  551.     int iTickCount;
  552.  
  553.     if (GameInit(hInstance)) 
  554.     {
  555.  
  556.         if (!GameLib()->Initialize(nCmdShow)) 
  557.         {
  558.             return FALSE;
  559.         }
  560.  
  561.         // Main message loop:
  562.         while (TRUE)
  563.         {
  564.             __try 
  565.             {
  566.                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  567.                 {
  568.                     if( msg.message == WM_QUIT )
  569.                         break;
  570.  
  571.                     TranslateMessage(&msg);
  572.                     DispatchMessage(&msg);
  573.                 } 
  574.                 else 
  575.                 {
  576.                     if (!GameLib()->GetHibernate())
  577.                     {
  578.                         iTickCount = GetTickCount();
  579.                         if (iTickCount > iNewTime)
  580.                         {
  581.                             iNewTime = iTickCount + GameLib()->GetFrameRate();
  582.                             GameEvent();
  583.                         }
  584.                     }
  585.                 }
  586.             }
  587.             __except(EXCEPTION_EXECUTE_HANDLER)
  588.             {
  589.                 MessageBox(NULL, _T("Exception error!"), _T("Error"), MB_OK | MB_ICONERROR);
  590.             }
  591.         } 
  592.  
  593.         return msg.wParam;
  594.     }
  595.  
  596.     GameEnd();
  597.     return 1;
  598. }
  599.  
  600. //////////////////////////////////////////////////////////////////////
  601. // MsgBox
  602. // Displays a pop-up message box
  603. //////////////////////////////////////////////////////////////////////
  604. void MsgBox(LPTSTR szMessage)
  605. {
  606.     MessageBox(GetForegroundWindow(), szMessage, GameLib()->szTitle, MB_OK | MB_ICONINFORMATION);
  607. }
  608.  
  609.